package com.atguigu.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * @author gaber
 * @date 2023/12/11 16:16:21
 * @description 客户端代码常用套路
 * 1、获取客户端对象
 * 2、执行相关的操作命令
 * 3、关闭资源
 */
public class HdfsClient {
    private FileSystem fs;

    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        // 连接的集群namenode地址
        URI uri = new URI("hdfs://node2:8020");
        // 创建一个配置文件
        Configuration configuration = new Configuration();

        // 优先级最高
        configuration.set("dfs.replication", "2");
        // 初始化用户
        String user = "root";
        // 1.获取客户端的对象
        fs = FileSystem.get(uri, configuration, user);
    }

    @After
    public void close() throws IOException {
        // 3.关闭资源
        fs.close();
    }

    // 创建目录
    @Test
    public void testmkdir() throws URISyntaxException, IOException, InterruptedException {
        // 2.创建目录
        fs.mkdirs(new Path("/xiyou/huaguoshan"));
    }

    /**
     * 参数优先级
     * hdfs-default.xml => hdfs-site.xml => 在项目资源的目录下的配置文件 =》 代码里面的配置
     * */
    // 上传文件
    @Test
    public void testPut() throws IOException {
        // 参数解读 参数一：表示删除原数据，参数二：是否允许覆盖，参数三：原数据路径，参数四：目的地路径
        fs.copyFromLocalFile(false, true, new Path("C://practice/spring-learning-summary/sunwukong.txt"), new Path("hdfs://node2/xiyou/huaguoshan"));
    }

    // 文件下载
    @Test
    public void testGet() throws IOException {
        // 参数解读 参数一：原文件是否删除，参数二：原文件文件HDFS，参数三：下载地址路径Win，参数四：是否校验
        fs.copyToLocalFile(false, new Path("hdfs://node2/xiyou/huaguoshan"), new Path("C://practice/spring-learning-summary"),false);
    }

    // 删除
    @Test
    public void testRm() throws IOException {
        // 参数解读 参数一：要删除的文件路径，参数二：是否递归删除，
        // 删除文件
        // fs.delete(new Path("hdfs://node2/jdk-8u212-linux-x64.tar.gz"), false);

        // 删除空目录
        // fs.delete(new Path("hdfs://node2/null"), false);

        // 删除非空目录
         fs.delete(new Path("/xiyou"), true);
    }

    // 文件的更名和移动
    @Test
    public void testMv() throws IOException {
        // 参数解读：参数一：原文件路径，参数二：目标文件路径
        // 对文件名称的修改
        // fs.rename(new Path("/input/word.txt"), new Path("/input/word1.txt"));

        // 文件的更名和移动
        // fs.rename(new Path("/input/word1.txt"), new Path("/word.txt"));

        // 目录更名
        fs.rename(new Path("/input"), new Path("/output"));
    }

    // 获取文件详细信息
    @Test
    public void fileDetail() throws IOException {
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);
        while (listFiles.hasNext()) {
            LocatedFileStatus fileStatus = listFiles.next();
            System.out.println("============" + fileStatus.getPath() + "==============");
            System.out.println(fileStatus.getPermission());
            System.out.println(fileStatus.getOwner());
            System.out.println(fileStatus.getGroup());
            System.out.println(fileStatus.getLen());
            System.out.println(fileStatus.getModificationTime());
            System.out.println(fileStatus.getReplication());
            System.out.println(fileStatus.getBlockSize());
            System.out.println(fileStatus.getPath().getName());
        }
    }

    // 判断是文件夹还是文件
    @Test
    public void testFile() throws IOException {
        FileStatus[] fileStatuses = fs.listStatus(new Path("/"));

        for (FileStatus fileStatus : fileStatuses) {
            if (fileStatus.isFile()) {
                System.out.println("文件：" + fileStatus.getPath().getName());
            } else {
                System.out.println("目录：" + fileStatus.getPath().getName());
            }
        }
    }
}
